package com.whjk.system.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.beust.jcommander.internal.Maps;
import com.whjk.system.biz.mapper.WhjkPackageRelInfoMapper;
import com.whjk.system.biz.mapper.WhjkZdjywhRuleMapper;
import com.whjk.system.biz.mapper.WhjkZdmxMapper;
import com.whjk.system.biz.service.*;
import com.whjk.system.data.dto.WhjkPackageRelInfoDto;
import com.whjk.system.data.dto.WhjkPersonResultDto;
import com.whjk.system.data.dto.WhjkZdjywhRuleDto;
import com.whjk.system.data.dto.WhjkZdmxDto;
import com.whjk.system.data.entity.*;
import com.whjk.system.data.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Service;

import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 诊断结果报告 服务实现类
 * </p>
 *
 * @author hl
 * @since 2023-06-28
 */
@Service
public class WhjkPackageRelInfoServiceImpl extends ServiceImpl<WhjkPackageRelInfoMapper, WhjkPackageRelInfo> implements WhjkPackageRelInfoService {

    @Autowired
    private WhjkZdmxMapper zdmxMapper;

    @Autowired
    private WhjkPackageRelService packageRelService;

    @Autowired
    private WhjkPersonService personService;

    @Autowired
    private WhjkZhxmService zhxmService;

    @Autowired
    private WhjkZdjywhInfoService whjkZdjywhInfoService;

    @Autowired
    private WhjkCjjgwhService cjjgwhService;
    /**
     * 通过关联表id查询子项结果
     *
     * @param id
     * @return
     */
    @Override
    public WhjkPersonResultDto getPersonResult(String id) {
        WhjkPersonResultDto whjkPersonResultDto = new WhjkPersonResultDto();
        //体检项目信息
        PackageRelVo packageRelVo = this.baseMapper.getPackageRelVo(id);
        whjkPersonResultDto.setWhjkPackageRel(packageRelVo);
        //体检子项结果
        whjkPersonResultDto.setItemList(
                this.baseMapper.getXm(new QueryWrapper<>()
                        .eq("wpri.del_flag", 0)
                        .eq("wx.del_flag", 0)
                        .eq("wpri.rel_id", id)).stream().map(i -> {
                    WhjkPackageRelInfoDto infoDto = new WhjkPackageRelInfoDto();
                    BeanUtils.copyProperties(i, infoDto);
                    infoDto.setJgList(cjjgwhService.list(new LambdaQueryWrapper<WhjkCjjgwh>()
                                    .eq(WhjkCjjgwh::getTjxmId, infoDto.getJcxmId())
                                    .eq(WhjkCjjgwh::getDelFlag, 0))
                            .stream().filter(f -> "%".equals(f.getXb()) || packageRelVo.getGender().equals(f.getXb()))
                            .collect(Collectors.toList()));
                    return infoDto;
                }).collect(Collectors.toList())
        );
        //体检诊断结果
        whjkPersonResultDto.setTjZdmxList(
                zdmxMapper.selectRelZdmx(new QueryWrapper<>()
                                .eq("wz.rel_id", id)
                                .eq("wz.del_flag", 0)
                                .eq("zhxm.del_flag", 0)
                                .eq("ks.del_flag", 0)
                                .eq("wpr.del_flag", 0))
                        .stream().peek(i -> i.setInfoList(
                                        whjkZdjywhInfoService.list(new LambdaQueryWrapper<WhjkZdjywhInfo>()
                                                .eq(WhjkZdjywhInfo::getDelFlag, 0)
                                                .eq(WhjkZdjywhInfo::getZdjyId, i.getZdjywhId()))
                                )
                        ).collect(Collectors.toList()));
        return whjkPersonResultDto;
    }

    /**
     * 根据关联表id查询历次子项体检结果
     *
     * @param id
     * @return
     */
    @Override
    public List<PackageRelInfoVo> getBeforeResult(String id) {
        //体检组合项目id
        WhjkPackageRel rel = packageRelService.getById(id);
        //多次体检的多个id
        List<String> peIds = this.baseMapper.getAllPeId(id);
        //当没有基础项目结果时返回为空
        if (peIds.size() == 0) {
            return new ArrayList<>();
        }
        //获取组合项目名称
        String mc = zhxmService.getById(rel.getXmId()).getZhmc();
        return this.baseMapper.getXm(new QueryWrapper<>()
                        .eq("wpri.zhxm_id", rel.getXmId())
                        .eq("wpri.del_flag", 0)
                        .eq("wx.del_flag", 0)
                        .in("wpri.pe_id", peIds))
                .stream().map(i -> {
                    PackageRelInfoVo infoVo = new PackageRelInfoVo();
                    BeanUtils.copyProperties(i, infoVo);
                    infoVo.setZhmc(mc);
                    infoVo.setCheckTime(packageRelService.getById(i.getRelId()).getCheckTime());
                    return infoVo;
                }).filter(f -> "1".equals(f.getCheckStatus())).collect(Collectors.toList());
    }

    @Override
    public List<PackageRelVo> getSummarizeResult(String id) {
        //根据用户id查询所有的体检结果
        List<WhjkPackageRelInfoDto> infoList = this.baseMapper.getSummarizeResult(id);
        return packageRelService.list(new LambdaQueryWrapper<WhjkPackageRel>()
                        .eq(WhjkPackageRel::getPeId, id)
                        .eq(WhjkPackageRel::getDelFlag, 0))
                .stream().map(i -> {
                    //体检组合分类显示
                    PackageRelVo packageRelVo = new PackageRelVo();
                    BeanUtils.copyProperties(i, packageRelVo);
                    packageRelVo.setZhmc(zhxmService.getById(packageRelVo.getXmId()).getZhmc());
                    packageRelVo.setPackageRelInfoVoList(
                            infoList.stream().filter(f ->
                                    //按组合分类
                                    f.getRelId().equals(i.getId())
                            ).collect(Collectors.toList()).stream().map(m -> {
                                //设置体检时间
                                PackageRelInfoVo packageRelInfoVo = new PackageRelInfoVo();
                                BeanUtils.copyProperties(m, packageRelInfoVo);
                                packageRelInfoVo.setCheckTime(i.getCheckTime());
                                return packageRelInfoVo;
                            }).collect(Collectors.toList())
                    );
                    return packageRelVo;
                }).collect(Collectors.toList());
    }

    @Override
    public List<BeforeContrastResultVo> getContrastResult(String id) {
        List<String> peIds = personService.list(new LambdaQueryWrapper<WhjkPerson>()
                        .eq(WhjkPerson::getIdCard, personService.getById(id).getIdCard())
                        .eq(WhjkPerson::getDelFlag, 0))
                .stream().map(WhjkPerson::getId)
                .collect(Collectors.toList());
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        List<BeforeContrastResultVo> VoList = this.baseMapper.getBeforeResultZhxm(peIds);
        return VoList.stream().peek(m -> {
            //标题list
            List<Map<String, String>> titleList = new ArrayList<>();
            //结果list
            List<Map<String, String>> jgList = new ArrayList<>();
            //插入固定map集合
            Map<String, String> t1 = new HashMap<>();
            t1.put("label", "体检明细项目");
            t1.put("name", "jcxmName");
            titleList.add(t1);
            if ("1".equals(m.getJclx()) || "2".equals(m.getJclx())) {
                Map<String, String> t2 = new HashMap<>();
                t2.put("label", "单位");
                t2.put("name", "dw");
                titleList.add(t2);
            }
            //所有基础项目结果
            List<PackageRelInfoVo> beforeResultXmList = this.baseMapper.getBeforeResultXm(peIds, m.getXmId());
            //循环插入标题时间map集合
            beforeResultXmList.stream().collect(Collectors.groupingBy(PackageRelInfoVo::getCheckTime))
                    .keySet().forEach(f -> {
                        Map<String, String> t = new HashMap<>();
                        t.put("label", f.format(formatter));
                        t.put("name", f.format(formatter));
                        titleList.add(t);
                    });
            //循环插入标题结果map集合
            beforeResultXmList.forEach(f -> {
                if (f.getJcxmName() == null) {
                    f.setJcxmName(" ");
                } else if (f.getDw() == null) {
                    f.setDw(" ");
                }
                List<Map<String, String>> maps = jgList.stream().filter(map ->
                        f.getJcxmName().equals(map.get("jcxmName"))
                ).collect(Collectors.toList());

                if (maps.size() > 0) {
                    maps.get(0).put(f.getCheckTime().format(formatter), f.getCheckResult());
                } else {
                    Map<String, String> j = new HashMap<>();
                    j.put("jcxmName", f.getJcxmName());
                    j.put("dw", f.getDw());
                    j.put(f.getCheckTime().format(formatter), f.getCheckResult());
                    jgList.add(j);
                }

            });
            m.setTitleList(titleList);
            m.setJgList(jgList);
        }).collect(Collectors.toList());
    }

    @Override
    public List<AnomalyOverviewVo> getAnomaly(String peId) {
        List<AnomalyOverviewVo> lsit= new ArrayList<>();

        List<WhjkZdmxDto> zdmxDtos = zdmxMapper.selectRelZdmx(new QueryWrapper<>().eq("wz.del_flag", 0).eq("wz.pe_id", peId));
        List<String> ksmcs = zdmxDtos.stream().map(WhjkZdmxDto::getKsmc).distinct().collect(Collectors.toList());

        List<BeforeContrastResultVo> VoList = this.baseMapper.getBeforeResultZhxm(Collections.singletonList(peId));
        List<BeforeContrastResultVo> filteredVoList = VoList.stream()
                .peek(m -> {
                    List<PackageRelInfoVo> beforeResultXmList = this.baseMapper.getBeforeResultXm(Collections.singletonList(peId), m.getXmId());
                    beforeResultXmList = beforeResultXmList.stream()
                            .filter(f -> f.getIsAbnormal() != 0)
                            .peek(jcxms -> {
                                List<WhjkZdmxDto> filteredZdmxDtos = zdmxDtos.stream()
                                        .filter(zdmxDto -> jcxms.getJcxmId().equals(zdmxDto.getJcxmId()))
                                        .collect(Collectors.toList());
                                if (!filteredZdmxDtos.isEmpty()) {
                                    jcxms.setZdjg(filteredZdmxDtos.get(0).getZdjg());
                                }
                            }).collect(Collectors.toList());
                    m.setJgList(beforeResultXmList);
                })
                .filter(m -> !m.getJgList().isEmpty())
                .collect(Collectors.toList());

        for (String ksmc : ksmcs) {
            AnomalyOverviewVo anomalyOverviewVo = new AnomalyOverviewVo();
            anomalyOverviewVo.setKsmc(ksmc);

            List<String> zhxmIds = zdmxDtos.stream()
                    .filter(zdmxDto -> zdmxDto.getKsmc().equals(ksmc))
                    .map(WhjkZdmxDto::getZhxmId)
                    .distinct()
                    .collect(Collectors.toList());

            List<BeforeContrastResultVo> zhDtoList = filteredVoList.stream()
                    .filter(m -> m.getJgList() != null && zhxmIds.contains(m.getXmId()))
                    .collect(Collectors.toList());
            anomalyOverviewVo.setAnomalyZHDtoList(zhDtoList);
            lsit.add(anomalyOverviewVo);

        }
        return lsit.stream().filter(m -> !m.getAnomalyZHDtoList().isEmpty()).collect(Collectors.toList());
    }

    @Override
    public List<MedicalAdviceVo> medicalAdvice(String peid) {
        List<MedicalAdviceVo> adviceVo = this.baseMapper.queryMedicalAdvice(new QueryWrapper<>()
                .eq("info.del_flag", 0)
                .eq("t2.del_flag", 0)
                .eq("t2.pe_id", peid)
                .gt("info.is_abnormal", 0)
        );
        return adviceVo.stream().map(m -> {
            List<WhjkZdjywhInfo> list = whjkZdjywhInfoService.list(new LambdaQueryWrapper<WhjkZdjywhInfo>()
                    .eq(WhjkZdjywhInfo::getDelFlag, 0)
                    .eq(WhjkZdjywhInfo::getZdjyId, m.getZdjyId())
            );
            m.setJy(list);
            return m;
        }).collect(Collectors.toList());
    }

    @Override
    public BeforeContrastResultVo getResult(String peid, String zhxmId){


        BeforeContrastResultVo beforeContrastResultVo = new BeforeContrastResultVo();
        WhjkZhxm zhxm = zhxmService.getById(zhxmId);
        List<PackageRelInfoVo> beforeResultXmList = this.baseMapper.getBeforeResultXm(Collections.singletonList(peid), zhxmId);

        Map<String, String> t1 = new HashMap<>();
        t1.put("label", "检查时间");
        t1.put("name", "checkTime");
        Map<String, String> t2 = new HashMap<>();
        t2.put("label", "结果");
        t2.put("name", "checkResult");
        Map<String, String> t3 = new HashMap<>();
        t3.put("label", "单位");
        t3.put("name", "dw");
        Map<String, String> t4 = new HashMap<>();
        t4.put("label", "体检明细项目");
        t4.put("name", "jcxmName");
        Map<String, String> t5 = new HashMap<>();
        t5.put("label", "检查范围");
        t5.put("name", "jcfw");
        Map<String, String> t6 = new HashMap<>();
        t6.put("label", "检查部位");
        t6.put("name", "checkPart");
        Map<String, String> t7 = new HashMap<>();
        t7.put("label", "检查小结");
        t7.put("name", "reference");

        List<Map<String, String>> titleList = new ArrayList<>();

        switch (zhxm.getJclx()) {
            case "1":
                titleList.add(t1);
                titleList.add(t4);
                titleList.add(t2);
                titleList.add(t3);
                break;
            case "2":
                titleList.add(t1);
                titleList.add(t4);
                titleList.add(t2);
                titleList.add(t3);
                titleList.add(t5);
                break;
            default:
                titleList.add(t1);
                titleList.add(t6);
                titleList.add(t2);
                titleList.add(t7);
                break;
        }

        beforeContrastResultVo.setTitleList(titleList);
        beforeContrastResultVo.setJgList(beforeResultXmList);

        return beforeContrastResultVo;
    }

    @Override
    public List<BeforeContrastResultVo> summaryItem(String idCard) {
        List<String> peIds = personService.list(new LambdaQueryWrapper<WhjkPerson>()
                        .eq(WhjkPerson::getIdCard,idCard)
                        .eq(WhjkPerson::getDelFlag, 0))
                .stream().map(WhjkPerson::getId)
                .collect(Collectors.toList());

       return this.baseMapper.getBeforeResultZhxm(peIds);
    }
}